package com.gateway.security.authorization.checker;

import com.gateway.common.dto.ApiDefinition;
import com.gateway.common.enums.AuthorizationTypeEnum;
import com.gateway.plugin.security.oauth2.authorization.ScopeAuthorizationChecker;
import com.gateway.security.common.authorization.AuthorizationChecker;
import com.gateway.security.common.authorization.DeniedAuthorizationChecker;
import com.gateway.plugin.security.uaa.authorization.ApiAuthorizationChecker;
import com.google.common.collect.Maps;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.core.Authentication;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * @program: api-gateway
 * @description:
 * @author: YuKai Fan
 * @create: 2025/2/11 22:47
 **/
public class AuthorizationCheckerFactory {
    private static final Map<String, AuthorizationChecker> checkerMap;

    static {
        checkerMap = Maps.newHashMapWithExpectedSize(AuthorizationTypeEnum.values().length);
        checkerMap.put(AuthorizationTypeEnum.API.getType(), new ApiAuthorizationChecker());
        checkerMap.put(AuthorizationTypeEnum.SCOPE.getType(), new ScopeAuthorizationChecker());
    }

    private AuthorizationCheckerFactory() {
    }

    /**
     * New instance ClientPrincipalConverter
     *
     * @param type the Authentication type
     * @return the ClientPrincipalConverter
     */
    public static AuthorizationChecker newInstance(final String type) {
        return checkerMap.getOrDefault(type, DeniedAuthorizationChecker.getInstance());
    }

    public static Mono<AuthorizationDecision> check(Mono<Authentication> authentication, ServerWebExchange exchange, ApiDefinition apiDefinition) {
        return newInstance(apiDefinition.getAuthorizationType().getType()).check(authentication, exchange, apiDefinition);
    }
}
